package cn.wolfcode.service.impl;

import cn.wolfcode.domain.Permission;
import cn.wolfcode.mapper.PermissionMapper;
import cn.wolfcode.query.QueryObject;
import cn.wolfcode.service.IPermissionService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class PermissionServiceImpl implements IPermissionService {

	@Autowired
	private PermissionMapper permissionMapper;
	@Autowired
	private ApplicationContext clz;

	public void reload() {
		// 数据库中的所有表达式
		List<String> expressions = permissionMapper.selectAllExpression();
		// 拿到所有的控制器
		Map<String, Object> map = clz.getBeansWithAnnotation(Controller.class);
		// 拿到所有控制器的对象
		Collection<Object> values = map.values();
		for (Object value : values) {
			// 判断是否是cglib 代理对象,如果不是就跳过
			if(!AopUtils.isCglibProxy(value)){
				continue;
			}
			// 代理对象方法上的注解不能被继承,所以不能获取到注解
			// 控制器的字节码对象(contorller 是代理对象,获取它的父类,获取所有方法)
			Class<?> controller = value.getClass().getSuperclass();
			Method[] methods = controller.getDeclaredMethods();
			for (Method method : methods) {
				// 拿到在方法上的自定义注解的对象
				RequiresPermissions annotation = method.getAnnotation(RequiresPermissions.class);
				// 如果注解不为空,则说明方法有贴注解
				if(annotation != null){
					String name = annotation.value()[1];
					String expression = annotation.value()[0];
					// 如果数据库没有这条表达式,则添加进去
					if(!expressions.contains(expression)){
						Permission permission = new Permission(null,name,expression);
						permissionMapper.insert(permission);
					}
				}
			}
		}
	}

	public void delete(Long id) {
		permissionMapper.delete(id);
	}

	public List<Permission> selectAll() {
		return permissionMapper.selectAll();
	}

	public PageInfo query(QueryObject qo) {
		PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
		return new PageInfo(permissionMapper.selectForList(qo));
	}
}
